@@ -1,5 +1,7 @@ |
||
| 1 | 1 |
module Agents |
| 2 | 2 |
class PostAgent < Agent |
| 3 |
+ include WebRequestConcern |
|
| 4 |
+ |
|
| 3 | 5 |
cannot_create_events! |
| 4 | 6 |
|
| 5 | 7 |
default_schedule "never" |
@@ -13,7 +15,11 @@ module Agents |
||
| 13 | 15 |
|
| 14 | 16 |
By default, non-GETs will be sent with form encoding (`application/x-www-form-urlencoded`). Change `content_type` to `json` to send JSON instead. |
| 15 | 17 |
|
| 16 |
- The `headers` field is optional. When present, it should be a hash of headers to send with the request. |
|
| 18 |
+ Other Options: |
|
| 19 |
+ |
|
| 20 |
+ * `headers` - When present, it should be a hash of headers to send with the request. |
|
| 21 |
+ * `basic_auth` - Specify HTTP basic auth parameters: `"username:password"`, or `["username", "password"]`. |
|
| 22 |
+ * `user_agent` - A custom User-Agent name (default: "Faraday v#{Faraday::VERSION}").
|
|
| 17 | 23 |
MD |
| 18 | 24 |
|
| 19 | 25 |
event_description "Does not produce events." |
@@ -40,10 +46,6 @@ module Agents |
||
| 40 | 46 |
(interpolated['method'].presence || 'post').to_s.downcase |
| 41 | 47 |
end |
| 42 | 48 |
|
| 43 |
- def headers |
|
| 44 |
- interpolated['headers'].presence || {}
|
|
| 45 |
- end |
|
| 46 |
- |
|
| 47 | 49 |
def validate_options |
| 48 | 50 |
unless options['post_url'].present? && options['expected_receive_period_in_days'].present? |
| 49 | 51 |
errors.add(:base, "post_url and expected_receive_period_in_days are required fields") |
@@ -64,6 +66,8 @@ module Agents |
||
| 64 | 66 |
unless headers.is_a?(Hash) |
| 65 | 67 |
errors.add(:base, "if provided, headers must be a hash") |
| 66 | 68 |
end |
| 69 |
+ |
|
| 70 |
+ validate_web_request_options! |
|
| 67 | 71 |
end |
| 68 | 72 |
|
| 69 | 73 |
def receive(incoming_events) |
@@ -81,48 +85,32 @@ module Agents |
||
| 81 | 85 |
handle interpolated['payload'].presence || {}
|
| 82 | 86 |
end |
| 83 | 87 |
|
| 84 |
- def generate_uri(params = nil, payload = {})
|
|
| 85 |
- uri = URI interpolated(payload)[:post_url] |
|
| 86 |
- uri.query = URI.encode_www_form(Hash[URI.decode_www_form(uri.query || '')].merge(params)) if params |
|
| 87 |
- uri |
|
| 88 |
- end |
|
| 89 |
- |
|
| 90 | 88 |
private |
| 91 | 89 |
|
| 92 | 90 |
def handle(data, payload = {})
|
| 93 |
- if method == 'post' |
|
| 94 |
- post_data(data, payload, Net::HTTP::Post) |
|
| 95 |
- elsif method == 'put' |
|
| 96 |
- post_data(data, payload, Net::HTTP::Put) |
|
| 97 |
- elsif method == 'delete' |
|
| 98 |
- post_data(data, payload, Net::HTTP::Delete) |
|
| 99 |
- elsif method == 'patch' |
|
| 100 |
- post_data(data, payload, Net::HTTP::Patch) |
|
| 101 |
- elsif method == 'get' |
|
| 102 |
- get_data(data, payload) |
|
| 91 |
+ url = interpolated(payload)[:post_url] |
|
| 92 |
+ headers = headers() |
|
| 93 |
+ |
|
| 94 |
+ case method |
|
| 95 |
+ when 'get', 'delete' |
|
| 96 |
+ params, body = data, nil |
|
| 97 |
+ when 'post', 'put', 'patch' |
|
| 98 |
+ params = nil |
|
| 99 |
+ |
|
| 100 |
+ case interpolated(payload)['content_type'] |
|
| 101 |
+ when 'json' |
|
| 102 |
+ headers['Content-Type'] = 'application/json; charset=utf-8' |
|
| 103 |
+ body = data.to_json |
|
| 104 |
+ else |
|
| 105 |
+ body = data |
|
| 106 |
+ end |
|
| 103 | 107 |
else |
| 104 | 108 |
error "Invalid method '#{method}'"
|
| 105 | 109 |
end |
| 106 |
- end |
|
| 107 |
- |
|
| 108 |
- def post_data(data, payload, request_type = Net::HTTP::Post) |
|
| 109 |
- uri = generate_uri(nil, payload) |
|
| 110 |
- req = request_type.new(uri.request_uri, headers) |
|
| 111 |
- |
|
| 112 |
- if interpolated(payload)['content_type'] == 'json' |
|
| 113 |
- req.set_content_type('application/json', 'charset' => 'utf-8')
|
|
| 114 |
- req.body = data.to_json |
|
| 115 |
- else |
|
| 116 |
- req.form_data = data |
|
| 117 |
- end |
|
| 118 |
- |
|
| 119 |
- Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == "https") { |http| http.request(req) }
|
|
| 120 |
- end |
|
| 121 | 110 |
|
| 122 |
- def get_data(data, payload) |
|
| 123 |
- uri = generate_uri(data, payload) |
|
| 124 |
- req = Net::HTTP::Get.new(uri.request_uri, headers) |
|
| 125 |
- Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == "https") { |http| http.request(req) }
|
|
| 111 |
+ faraday.run_request(method.to_sym, url, body, headers) { |request|
|
|
| 112 |
+ request.params.update(params) if params |
|
| 113 |
+ } |
|
| 126 | 114 |
end |
| 127 | 115 |
end |
| 128 | 116 |
end |
@@ -2,16 +2,17 @@ require 'spec_helper' |
||
| 2 | 2 |
|
| 3 | 3 |
describe Agents::PostAgent do |
| 4 | 4 |
before do |
| 5 |
- @valid_params = {
|
|
| 6 |
- :name => "somename", |
|
| 7 |
- :options => {
|
|
| 8 |
- 'post_url' => "http://www.example.com", |
|
| 9 |
- 'expected_receive_period_in_days' => 1, |
|
| 10 |
- 'payload' => {
|
|
| 11 |
- 'default' => 'value' |
|
| 12 |
- } |
|
| 5 |
+ @valid_options = {
|
|
| 6 |
+ 'post_url' => "http://www.example.com", |
|
| 7 |
+ 'expected_receive_period_in_days' => 1, |
|
| 8 |
+ 'payload' => {
|
|
| 9 |
+ 'default' => 'value' |
|
| 13 | 10 |
} |
| 14 | 11 |
} |
| 12 |
+ @valid_params = {
|
|
| 13 |
+ name: "somename", |
|
| 14 |
+ options: @valid_options |
|
| 15 |
+ } |
|
| 15 | 16 |
|
| 16 | 17 |
@checker = Agents::PostAgent.new(@valid_params) |
| 17 | 18 |
@checker.user = users(:jane) |
@@ -26,22 +27,37 @@ describe Agents::PostAgent do |
||
| 26 | 27 |
} |
| 27 | 28 |
} |
| 28 | 29 |
@requests = 0 |
| 29 |
- @sent_requests = { Net::HTTP::Get => [], Net::HTTP::Post => [], Net::HTTP::Put => [], Net::HTTP::Delete => [], Net::HTTP::Patch => [] }
|
|
| 30 |
- |
|
| 31 |
- stub.any_instance_of(Agents::PostAgent).post_data { |data, payload, type| @requests += 1; @sent_requests[type] << data }
|
|
| 32 |
- stub.any_instance_of(Agents::PostAgent).get_data { |data, payload| @requests += 1; @sent_requests[Net::HTTP::Get] << data }
|
|
| 30 |
+ @sent_requests = Hash.new { |hash, method| hash[method] = [] }
|
|
| 31 |
+ |
|
| 32 |
+ stub_request(:any, /:/).to_return { |request|
|
|
| 33 |
+ method = request.method |
|
| 34 |
+ @requests += 1 |
|
| 35 |
+ case method |
|
| 36 |
+ when :get, :delete |
|
| 37 |
+ data = request.uri.query |
|
| 38 |
+ else |
|
| 39 |
+ if data = request.body |
|
| 40 |
+ case request.headers['Content-Type'] |
|
| 41 |
+ when /json/ |
|
| 42 |
+ data = ActiveSupport::JSON.decode(data) |
|
| 43 |
+ end |
|
| 44 |
+ end |
|
| 45 |
+ end |
|
| 46 |
+ @sent_requests[method] << data |
|
| 47 |
+ { status: 200, body: "ok" }
|
|
| 48 |
+ } |
|
| 33 | 49 |
end |
| 34 | 50 |
|
| 51 |
+ it_behaves_like WebRequestConcern |
|
| 52 |
+ |
|
| 35 | 53 |
describe "making requests" do |
| 36 | 54 |
it "can make requests of each type" do |
| 37 |
- { 'get' => Net::HTTP::Get, 'put' => Net::HTTP::Put,
|
|
| 38 |
- 'post' => Net::HTTP::Post, 'patch' => Net::HTTP::Patch, |
|
| 39 |
- 'delete' => Net::HTTP::Delete }.each.with_index do |(verb, type), index| |
|
| 55 |
+ %w[get put post patch delete].each.with_index(1) do |verb, index| |
|
| 40 | 56 |
@checker.options['method'] = verb |
| 41 | 57 |
@checker.should be_valid |
| 42 | 58 |
@checker.check |
| 43 |
- @requests.should == index + 1 |
|
| 44 |
- @sent_requests[type].length.should == 1 |
|
| 59 |
+ @requests.should == index |
|
| 60 |
+ @sent_requests[verb.to_sym].length.should == 1 |
|
| 45 | 61 |
end |
| 46 | 62 |
end |
| 47 | 63 |
end |
@@ -59,11 +75,11 @@ describe Agents::PostAgent do |
||
| 59 | 75 |
lambda {
|
| 60 | 76 |
lambda {
|
| 61 | 77 |
@checker.receive([@event, event1]) |
| 62 |
- }.should change { @sent_requests[Net::HTTP::Post].length }.by(2)
|
|
| 63 |
- }.should_not change { @sent_requests[Net::HTTP::Get].length }
|
|
| 78 |
+ }.should change { @sent_requests[:post].length }.by(2)
|
|
| 79 |
+ }.should_not change { @sent_requests[:get].length }
|
|
| 64 | 80 |
|
| 65 |
- @sent_requests[Net::HTTP::Post][0].should == @event.payload.merge('default' => 'value')
|
|
| 66 |
- @sent_requests[Net::HTTP::Post][1].should == event1.payload |
|
| 81 |
+ @sent_requests[:post][0].should == @event.payload.merge('default' => 'value').to_query
|
|
| 82 |
+ @sent_requests[:post][1].should == event1.payload.to_query |
|
| 67 | 83 |
end |
| 68 | 84 |
|
| 69 | 85 |
it "can make GET requests" do |
@@ -72,10 +88,10 @@ describe Agents::PostAgent do |
||
| 72 | 88 |
lambda {
|
| 73 | 89 |
lambda {
|
| 74 | 90 |
@checker.receive([@event]) |
| 75 |
- }.should change { @sent_requests[Net::HTTP::Get].length }.by(1)
|
|
| 76 |
- }.should_not change { @sent_requests[Net::HTTP::Post].length }
|
|
| 91 |
+ }.should change { @sent_requests[:get].length }.by(1)
|
|
| 92 |
+ }.should_not change { @sent_requests[:post].length }
|
|
| 77 | 93 |
|
| 78 |
- @sent_requests[Net::HTTP::Get][0].should == @event.payload.merge('default' => 'value')
|
|
| 94 |
+ @sent_requests[:get][0].should == @event.payload.merge('default' => 'value').to_query
|
|
| 79 | 95 |
end |
| 80 | 96 |
|
| 81 | 97 |
it "can skip merging the incoming event when no_merge is set, but it still interpolates" do |
@@ -84,7 +100,7 @@ describe Agents::PostAgent do |
||
| 84 | 100 |
'key' => 'it said: {{ someotherkey.somekey }}'
|
| 85 | 101 |
} |
| 86 | 102 |
@checker.receive([@event]) |
| 87 |
- @sent_requests[Net::HTTP::Post].first.should == { 'key' => 'it said: value' }
|
|
| 103 |
+ @sent_requests[:post].first.should == { 'key' => 'it said: value' }.to_query
|
|
| 88 | 104 |
end |
| 89 | 105 |
end |
| 90 | 106 |
|
@@ -92,9 +108,9 @@ describe Agents::PostAgent do |
||
| 92 | 108 |
it "sends options['payload'] as a POST request" do |
| 93 | 109 |
lambda {
|
| 94 | 110 |
@checker.check |
| 95 |
- }.should change { @sent_requests[Net::HTTP::Post].length }.by(1)
|
|
| 111 |
+ }.should change { @sent_requests[:post].length }.by(1)
|
|
| 96 | 112 |
|
| 97 |
- @sent_requests[Net::HTTP::Post][0].should == @checker.options['payload'] |
|
| 113 |
+ @sent_requests[:post][0].should == @checker.options['payload'].to_query |
|
| 98 | 114 |
end |
| 99 | 115 |
|
| 100 | 116 |
it "sends options['payload'] as a GET request" do |
@@ -102,10 +118,10 @@ describe Agents::PostAgent do |
||
| 102 | 118 |
lambda {
|
| 103 | 119 |
lambda {
|
| 104 | 120 |
@checker.check |
| 105 |
- }.should change { @sent_requests[Net::HTTP::Get].length }.by(1)
|
|
| 106 |
- }.should_not change { @sent_requests[Net::HTTP::Post].length }
|
|
| 121 |
+ }.should change { @sent_requests[:get].length }.by(1)
|
|
| 122 |
+ }.should_not change { @sent_requests[:post].length }
|
|
| 107 | 123 |
|
| 108 |
- @sent_requests[Net::HTTP::Get][0].should == @checker.options['payload'] |
|
| 124 |
+ @sent_requests[:get][0].should == @checker.options['payload'].to_query |
|
| 109 | 125 |
end |
| 110 | 126 |
end |
| 111 | 127 |
|
@@ -208,34 +224,4 @@ describe Agents::PostAgent do |
||
| 208 | 224 |
@checker.should be_valid |
| 209 | 225 |
end |
| 210 | 226 |
end |
| 211 |
- |
|
| 212 |
- describe "#generate_uri" do |
|
| 213 |
- it "merges params with any in the post_url" do |
|
| 214 |
- @checker.options['post_url'] = "http://example.com/a/path?existing_param=existing_value" |
|
| 215 |
- uri = @checker.generate_uri("some_param" => "some_value", "another_param" => "another_value")
|
|
| 216 |
- uri.request_uri.should == "/a/path?existing_param=existing_value&some_param=some_value&another_param=another_value" |
|
| 217 |
- end |
|
| 218 |
- |
|
| 219 |
- it "works fine with urls that do not have a query" do |
|
| 220 |
- @checker.options['post_url'] = "http://example.com/a/path" |
|
| 221 |
- uri = @checker.generate_uri("some_param" => "some_value", "another_param" => "another_value")
|
|
| 222 |
- uri.request_uri.should == "/a/path?some_param=some_value&another_param=another_value" |
|
| 223 |
- end |
|
| 224 |
- |
|
| 225 |
- it "just returns the post_uri when no params are given" do |
|
| 226 |
- @checker.options['post_url'] = "http://example.com/a/path?existing_param=existing_value" |
|
| 227 |
- uri = @checker.generate_uri |
|
| 228 |
- uri.host.should == 'example.com' |
|
| 229 |
- uri.scheme.should == 'http' |
|
| 230 |
- uri.request_uri.should == "/a/path?existing_param=existing_value" |
|
| 231 |
- end |
|
| 232 |
- |
|
| 233 |
- it "interpolates when receiving a payload" do |
|
| 234 |
- @checker.options['post_url'] = "https://{{ domain }}/{{ variable }}?existing_param=existing_value"
|
|
| 235 |
- uri = @checker.generate_uri({ "some_param" => "some_value", "another_param" => "another_value" }, { 'domain' => 'google.com', 'variable' => 'a_variable' })
|
|
| 236 |
- uri.request_uri.should == "/a_variable?existing_param=existing_value&some_param=some_value&another_param=another_value" |
|
| 237 |
- uri.host.should == 'google.com' |
|
| 238 |
- uri.scheme.should == 'https' |
|
| 239 |
- end |
|
| 240 |
- end |
|
| 241 |
-end |
|
| 227 |
+end |